package com.cn.xiaonuo.common.utils;

import org.joda.time.DateTime;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public abstract class DateUtils {
	public  static  SimpleDateFormat ymd=new SimpleDateFormat("yyyy-MM-dd");
	public  static  SimpleDateFormat yMdHmsS=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public  static  String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
	public static final String DEFAULT_PATTERN = "yyyyMMddhhmmss";
	//年-月-日 时:分:秒.毫秒
	public static final String FULLTIMEBY_yMdHmsS = "yyyy-MM-dd HH:mm:ss.SSS";

	public static String getSystemDate() {
		return formatDate(getSysDateTime(), DEFAULT_PATTERN);
	}

	public static String newDate(String format){
		SimpleDateFormat fmt=new SimpleDateFormat(format);
		return fmt.format(new Date());
	}

	public static String formatDate(Date date, String pattern){
		DateFormat df = new SimpleDateFormat(pattern);
		return df.format(date);
	}

	public static Date parseDate(String dateStr, String pattern){
		DateFormat df = new SimpleDateFormat(pattern);
		try {
			return df.parse(dateStr);
		} catch (ParseException e) {
			throw new RuntimeException("Error while parse date", e);
		}
	}

	public static Date getSysDateTime(){
		return new Date();
	}

	public static Date getSysDate(){
		return getDate(getSysDateTime());
	}

	public static Date getDate(Date date){
		if (date == null) return null;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return cal.getTime();
	}

	public static Date add(Date date, int dateField, int mount){
		if (date == null) return null;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(dateField, mount);

		return cal.getTime();
	}

	public static int getYear(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.YEAR);
	}

	public static int getMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MONTH)+1;
	}

	public static int getDayOfMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * Sunday=1
	 * SATURDAY=7
	 * @param date
	 * @return
	 */
	public static int getDayOfWeek(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_WEEK);
	}

	public static int getDayOfYear(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_YEAR);

	}

	public static int getHour(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.HOUR_OF_DAY);
	}

	public static int getMinute(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MINUTE);
	}

	public static int getSecond(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.SECOND);
	}

	public static int getMillSecond(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MILLISECOND);
	}

	public static Timestamp getTimestamp(Date date){
		return new Timestamp(date.getTime());
	}

	public static java.sql.Date getSqlDate(Date date){
		return new java.sql.Date(date.getTime());
	}

	public static Date getDate(int year, int month, int day){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DAY_OF_MONTH, day);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return cal.getTime();
	}

	public static Date getDate(int year, int month, int day, int hour, int min, int second){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DAY_OF_MONTH, day);
		cal.set(Calendar.HOUR_OF_DAY, hour);
		cal.set(Calendar.MINUTE, min);
		cal.set(Calendar.SECOND, second);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	public static Date getFirstDateOfMonth(int year, int month){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return cal.getTime();
	}

	public static Date getLastDateOfMonth(int year, int month){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return cal.getTime();
	}

	public static Date getPreviousDate(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)-1);
		return cal.getTime();
	}

	public static Date getNextDate(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)+1);
		return cal.getTime();
	}

	public static Date getFirstDateOfMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH);
		return getFirstDateOfMonth(year, month);
	}

	public static Date getLastDateOfMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH);
		return getLastDateOfMonth(year, month);
	}

	/**
	 * 获得给定日期当周的WeekDay
	 * @param date
	 * @param weekOfDay		星期一是1，星期天是7
	 * @return
	 */
	public static Date getWeekDate(Date date, int weekOfDay){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		if (weekOfDay < 7){
			cal.set(Calendar.DAY_OF_WEEK, weekOfDay+1);
		}else{
			cal.set(Calendar.DAY_OF_WEEK, weekOfDay);//星期六
			cal.add(Calendar.DATE, weekOfDay-6);//往后推一天到周日
		}
		return cal.getTime();
	}

	/**
	 * 两个时间相差毫秒数
	 * @param start
	 * @param end
	 * @return
	 */
	public static Long minusMilliseconds(Date start, Date end,boolean ifswap){
		if (start.after(end)&&ifswap==true){//交换
			Date tmp = start;
			start = end;
			end = tmp;
		}

		return end.getTime()-start.getTime();
	}

	public static Long minusSeconds(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)/1000;
	}

	public static Long minusMinutes(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)/(1000*60);
	}

	public static Long minusHours(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)/(1000*60*60);
	}

	public static Long minusDay(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)/(1000*60*60*24);
	}

	//排除天数只计算小时部分
	public static Long minusHoursExceptDay(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)%(1000*60*60*24)/(1000*60);
	}
	//排除天数只计算分钟部分
	public static Long minusDayExceptHuors(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)%(1000*60*60)/(1000*60);
	}


	//返回天小时分字符串
	public static String getIntervalDayHourMinStr(Date start, Date end,String []unitdes,boolean ifswap){

	long days=minusSeconds(start, end,ifswap)/(60*60*24);//得到总天数

	long hours=minusHoursExceptDay(start, end,ifswap)/60;//得到最后一天小时数

	long minus=minusDayExceptHuors(start, end,ifswap);//得到最后一小时分钟数

		String rtStr=days+unitdes[0]+hours+unitdes[1]+minus+unitdes[2];

		return rtStr;
	}

	/**
	 * @param
	 */
	public static Calendar getUtCCalendar() {
	    //1、取得本地时间：
	    final Calendar cal = Calendar.getInstance();
	    System.out.println(cal.getTime());
	    //2、取得时间偏移量：
	    final int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
	    System.out.println(zoneOffset);
	    //3、取得夏令时差：
	    final int dstOffset = cal.get(Calendar.DST_OFFSET);
	    System.out.println(dstOffset);
	    //4、从本地时间里扣除这些差量，即可以取得UTC时间：
	    cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
	   return cal;
	}

	/*
	 * 根据生日计算年龄
	 */
	public static int getAge(Date birthDay){
		int age = 0;
		try{
			Calendar cal = Calendar.getInstance();
			if(birthDay == null || cal.before(birthDay)){
				System.err.println("DateUtils::getAge - birthDay is null or birthDay data error!");
			}
			else{
				int yearNow = cal.get(Calendar.YEAR);
				int monthNow = cal.get(Calendar.MONTH);
				int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
				cal.setTime(birthDay);

				int yearBirth = cal.get(Calendar.YEAR);
				int monthBirth = cal.get(Calendar.MONTH);
				int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
				age = yearNow - yearBirth;
				if (monthNow <= monthBirth) {
					if (monthNow == monthBirth) {
						if (dayOfMonthNow < dayOfMonthBirth)
							age--;
					}
					else {
						age--;
					}
				}
			}
		}
		catch(Exception ex){
			age = 0;
			ex.printStackTrace();
		}
		return age;
	}

	/**
	 * 验证是否正确的时间格式
	 * @param strDate
	 * @param pattern
	 * @return
	 */
	public static boolean isValidDate(String strDate, String pattern)
	{
	    boolean convertSuccess=true;
	    // 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
	    SimpleDateFormat format = new SimpleDateFormat(pattern);
	    try {
	    	// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
	         format.setLenient(false);
	         format.parse(strDate);
	     } catch (ParseException e) {
	         // e.printStackTrace();
	         convertSuccess=false;
	     }
	     return convertSuccess;
	}

	/*
	 * 将时间戳转换为时间
	 */
	public static String stampToDate(String s){
		String res;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long lt = new Long(s);
		Date date = new Date(lt);
		res = simpleDateFormat.format(date);
		return res;
	}

	/*
	 * 将时间戳转换为时间
	 */
	public static String stampToDateYMD(String s){
		String res;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		long lt = new Long(s);
		Date date = new Date(lt);
		res = simpleDateFormat.format(date);
		return res;
	}

	/*
	 * 将String时间类型换为时间Date
	 */
	public static Date stringToDate(String s) throws Exception {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.parse(s);
	}


	/**
	 * 将String时间类型换为时间Date然后加减天数
	 * @param number 天数，正数为加负数为减
	 * @param date 时间
	 * @return
	 */
	public static String getBeforeDay(int number ,String date) {
		try {
			//定义日期格式化的格式
			DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			Date dateClass = format.parse(date);
			Calendar calendar = Calendar.getInstance(); //使用Calendar日历类对日期进行加减
			calendar.setTime(dateClass);
			calendar.add(Calendar.DAY_OF_MONTH, number);
			dateClass = calendar.getTime();//获取加减以后的Date类型日期
			return format.format(dateClass);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	public static int compare_date(String DATE1, String DATE2) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");
		try {
			Date dt1 = df.parse(DATE1);
			Date dt2 = df.parse(DATE2);
			if (dt1.getTime() > dt2.getTime()) {
				return 1;
			} else if (dt1.getTime() < dt2.getTime()) {
				return -1;
			} else {
				return 0;
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return 0;
	}

	public static String getTimeStr(Date  date  ,int minte) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.MINUTE, minte);
		return sdf.format(calendar.getTime());
	}
	/**
	 * 对日期的【分钟】进行加/减
	 *
	 * @param date 日期
	 * @param minutes 分钟数，负数为减
	 * @return 加/减几分钟后的日期
	 */
	public static Date addDateMinutes(Date date, int minutes) {
		DateTime dateTime = new DateTime(date);
		return dateTime.plusMinutes(minutes).toDate();
	}
	public static Map<String, String> conversionTime(Long beginTime, Long endTime) {
		Map<String, String> map = new HashMap<>(16);
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		try {
			String begin = format.format(new Date(beginTime)) + " 00:00:00";
			String end = format.format(new Date(endTime)) + " 23:59:59";
			map.put("begin", begin);
			map.put("end", end);
		} catch (Exception e) {
			System.out.print("****************时间转换错误*******************");
			e.printStackTrace();
		}
		return map;
	}

	public static Map<String, String> converTime(Long beginTime, Long endTime) {
		Map<String, String> map = new HashMap<>(16);
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			String begin = format.format(new Date(beginTime));
			String end = format.format(new Date(endTime));
			map.put("begin", begin);
			map.put("end", end);
		} catch (Exception e) {
			System.out.print("****************时间转换错误*******************");
			e.printStackTrace();
		}
		return map;
	}
	/**
	 * 转换时间戳位时间格式
	 * @param timestamp 时间戳(long)
	 * @param timeFormat 转换的时间格式
	 * @return 时间
	 */
	public static String translateTimeToDate(Long timestamp, String timeFormat){
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormat);
		return simpleDateFormat.format(timestamp);
	}
	/**
	 * 获取当前系统时间的时间戳
	 * @return 时间戳
	 */
	public static Long getCurrentTime(){
		return System.currentTimeMillis();
	}

   /**
	* 日期格式化 日期格式为：yyyyMMdd
     * @param date  日期
     * @return  返回yyyy-MM-dd格式日期
     */
	public static String formatDateYyyyMMddHHmmss(Date date) {
		try {
			if(date != null){
				SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
				return df.format(date);
			}
		}catch (Exception e) {

		}
		return null;
	}

	/**
	 * 当前日期加减
	 * @param number 天数，正数为加负数为减
	 * @return
	 */
	public static String datePlusMinus(Integer number){
		Calendar calendar = Calendar.getInstance();
		Date date = new Date();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, number);
		String createTime = ymd.format(calendar.getTime());
		return createTime;
	}

	/**
	 * 当前日期加减
	 * @param number 天数，正数为加负数为减
	 * @return
	 */
	public static String datePlusMinus(Integer number,Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, number);
		String createTime = ymd.format(calendar.getTime());
		return createTime;
	}
}
